﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace SystemAnalizer.Algorithms
{
    public class Matrix
    {
        private double[][]	m_Matrix;
        private int		m_RowNumber;
        private int		m_ColumnNumber;
        private int		m_IsValid;  //Determinant Can Be Calculate Only
                                    //If m_IsValid!=-1

        public Matrix()
        {
            m_RowNumber = 0;
            m_ColumnNumber = 0;
        }
        public Matrix(int Row,int Column)
        {
            m_RowNumber=Row;
            m_ColumnNumber=Column;

            m_Matrix=new double[m_RowNumber][];

            for (int j=0;j<m_RowNumber;j++)
                m_Matrix[j]=new double[m_ColumnNumber];

            m_IsValid=((Row==Column) ? 0 : -1);

        }
        public Matrix(double [][] mat,int Row,int Column)
        {
            m_Matrix = mat;
            m_RowNumber = Row;
            m_ColumnNumber = Column;
        }
        public Matrix( Matrix mat)
        {

            int i,j;
            m_RowNumber=mat.GetRow();
            m_ColumnNumber=mat.GetColumn();
            m_Matrix=new double[m_RowNumber][];
            for (j=0;j<m_RowNumber;j++)
                m_Matrix[j]=new double[m_ColumnNumber];

            for(i=0;i<m_RowNumber;i++)
            for (j=0;j<m_ColumnNumber;j++)
                    m_Matrix[i][j]=mat.m_Matrix[i][j];

            m_IsValid=((m_RowNumber==m_ColumnNumber) ? 0 : -1); //Determinant Can Be Calculate Only
        }
       public void Create(int Row,int Column)
        {
            m_RowNumber=Row;
            m_ColumnNumber=Column;

            m_Matrix = new double[m_RowNumber][];

            for (int j=0;j<m_RowNumber;j++)
             m_Matrix[j]=new double[m_ColumnNumber];

            m_IsValid=((Row==Column) ? 0 : -1); //Determinant Can Be Calculate Only
                                        //When RowNumber==ColumnNumber

        }
        
        public Matrix   E()
        {
           int i;
           Zeros();
           if (m_IsValid!=-1)
           for (i = 0; i < m_RowNumber; i++)

           m_Matrix[i][i] = 1;

           return this;
        }
        public Matrix   Zeros()
        {
           int i,j;
            for (i = 0; i < m_RowNumber; i++)
                for (j = 0; j < m_ColumnNumber; j++)
                    this.m_Matrix[i][j] = 0;

            return this;
        }
        public Matrix   Ones()
        {
            int i,j;
            for (i = 0; i < m_RowNumber; i++)
                for (j = 0; j < m_RowNumber; j++)
                    this.m_Matrix[i][j] = 1;

            return this;
        }

        
       // public void	 Create(int Row,int Column);
        public double GetElem(int Row, int Column)
        {
            return m_Matrix[Row][Column];
        }
        public void	 SetElem(int Row, int Column, double Elem)
        {
            m_Matrix[Row][Column] = Elem;
        }
        public int	 GetRow() {return m_RowNumber;}

        public int	 GetColumn() {return m_ColumnNumber;}
        public void SetRow(int Row)  {m_RowNumber=Row;}
        public void	 SetColumn(int Column) {m_ColumnNumber=Column;}
        //public double[]  operator [] (int Index);

        //public operator mType**()const {return m_Matrix;}
         public static Matrix  operator+(Matrix mat1, Matrix mat2)
        {
            Matrix Tmp = mat1;
            //if ((mat1.m_RowNumber != mat1.GetRow()) || (mat1m_ColumnNumber != mat.GetColumn())) ;
                //throw Dimension_Error();
            for (int i = 0; i < mat1.m_RowNumber; i++)
                for (int j = 0; j < mat1.m_ColumnNumber; j++)
                        Tmp.m_Matrix[i][j]+=mat2.m_Matrix[i][j];
                return  Tmp;
        }
        //public Matrix& operator-=(const Matrix& mat);
         public static Matrix operator -(Matrix mat1, Matrix mat2)
        {
            Matrix Tmp=mat1;
            //if ((m_RowNumber !=mat.GetRow()) || (m_ColumnNumber!=mat.GetColumn())) ;
                //throw Dimension_Error();

            for (int  i=0;i<mat1.m_RowNumber;i++)
                for (int j=0;j<mat1.m_ColumnNumber;j++)
                        Tmp.m_Matrix[i][j]-=mat1.m_Matrix[i][j];
                return  Tmp;
        }

 
        public static Matrix operator*(Matrix mat1, Matrix mat2 )
        {
            //if(m_ColumnNumber!=mat1.GetRow());
                //throw Dimension_Error();
            int  r=mat2.GetColumn();
            Matrix Tmp = new Matrix(mat1.m_RowNumber, mat2.m_ColumnNumber);
            for (int g = 0; g < mat1.m_RowNumber; g++)
                for (int i=0;i<r;i++)
                {
                        double d=0;
                        for (int j = 0; j < mat2.m_ColumnNumber; j++)
                                d+=mat1.m_Matrix[g][j]*mat2.m_Matrix[j][i];
                        Tmp.m_Matrix[g][i]=d;
                }
                return Tmp;
        }


    }
}
